home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 3 / Info_Mac_1994-01.iso / Graphics / Utility / GL Viewer 1.1.1 / src ƒ / readfiles.c < prev    next >
Text File  |  1993-09-06  |  36KB  |  1,582 lines

  1. /*
  2.  * Mac hack of
  3.  * readfiles.c - routines to load images, fonts, and execution files.
  4.  *
  5.  * Copyright (c) 1991 by Patrick J. Naughton
  6.  */
  7.  
  8. #pragma segment Readfiles
  9.  
  10. #include "glassert.h"
  11. #include "grasp.h"
  12. #include "procImage.h"
  13. #include "exec.h"
  14. #include "fades.h"
  15.  
  16.  
  17. ImageStruct *image[MAXIMAGES];
  18. int         numimages = 0;
  19. FontStruct *font[MAXFONTS];
  20. int         numfonts = 0;
  21. ExecStruct *execRec[MAXEXECS];
  22. int         numexecs = 0;
  23.  
  24. extern ImageStruct *readgifimage();
  25. extern void        exitcheck (void);
  26.  
  27.  
  28. void
  29. lowerstr(s)
  30.     char       *s;
  31. {
  32.     while (*s)
  33.     {
  34.     if (*s >= 'A' && *s <= 'Z')
  35.         *s += 'a' - 'A';
  36.     s++;
  37.     }
  38. }
  39.  
  40. void
  41. hexdump(fp, n)
  42.     FILE       *fp;
  43.     int         n;
  44. {
  45.     long        ofs = ftell(fp);
  46.     int         i, j;
  47.     u_char      b[16];
  48.  
  49.     for (j = 0; j < n; j++) {
  50.     for (i = 0; i < 16; i++) {
  51.         b[i] = GetByte(fp);
  52.         fprintf(stderr,"%02x ", b[i]);
  53.     }
  54.     fprintf(stderr," ");
  55.     for (i = 0; i < 16; i++)
  56.         fprintf(stderr,"%c ", isprint(b[i]) ? b[i] : '.');
  57.     fprintf(stderr,"\n");
  58.     }
  59.     fseek(fp, ofs, 0);
  60. }
  61.  
  62. /*-
  63.         Border                                 Color Table
  64.         Color    Color       Palette   1            2              3
  65.         -----    -----       ------- -----------------------------------
  66.           0      Black          0    Green        Red             Brown
  67.           1      Blue           1    Cyan         Magenta         White
  68.           2      Green          2    Cyan         Red             White
  69.           3      Cyan           3    Bright Green Bright Red      Yellow
  70.           4      Red            4    Bright Cyan  Bright Magenta  White
  71.           5      Magenta        5    Bright Cyan  Bright Red      White
  72.           6      Brown       -------------------------------------------
  73.           7      Grey
  74.           8      Dark Grey (Bright Black)
  75.           9      Bright Blue
  76.          10      Bright Green
  77.          11      Bright Cyan
  78.          12      Bright Red
  79.          13      Bright Magenta
  80.          14      Yellow (Bright Brown)
  81.          15      White (Bright Grey)
  82. */
  83.  
  84. u_short     egapal[16][3] = {
  85.     {0x0000, 0x0000, 0x0000}, {0x0000, 0x0000, 0xaaaa},
  86.     {0x0000, 0xaaaa, 0x0000}, {0x0000, 0xaaaa, 0xaaaa},
  87.     {0xaaaa, 0x0000, 0x0000}, {0xaaaa, 0x0000, 0xaaaa},
  88.     {0xaaaa, 0x5555, 0x0000}, {0xaaaa, 0xaaaa, 0xaaaa},
  89.     {0x5555, 0x5555, 0x5555}, {0x5555, 0x5555, 0xffff},
  90.     {0x5555, 0xffff, 0x5555}, {0x5555, 0xffff, 0xffff},
  91.     {0xffff, 0x5555, 0x5555}, {0xffff, 0x5555, 0xffff},
  92.     {0xffff, 0xffff, 0x5555}, {0xffff, 0xffff, 0xffff}
  93. };
  94.  
  95. int         cgapal[3][6] = {
  96.     {2, 3, 3, 10, 11, 11},
  97.     {4, 5, 4, 12, 13, 12},
  98.     {6, 15, 15, 14, 15, 15}
  99. };
  100.  
  101.  
  102. Colormap CreateEGAcmap()
  103. {
  104.     Colormap    cmap;
  105.     XColor      colors[16];
  106.     unsigned long pixels[16];
  107.     unsigned long pmasks;
  108.     int         i;
  109.  
  110.     cmap = XCreateColormap(dsp, win, vis, AllocNone);
  111.     XAllocColorCells(dsp, cmap, True, &pmasks, 0, pixels, 16);
  112.  
  113.      for (i = 0; i < 16; i++) {
  114.     colors[i].pixel = pixels[i];
  115.     colors[i].red = egapal[i][0];
  116.     colors[i].green = egapal[i][1];
  117.     colors[i].blue = egapal[i][2];
  118.     colors[i].flags = DoRed | DoGreen | DoBlue;
  119.     }
  120.     XStoreColors(dsp, cmap, colors, 16);
  121.     return cmap;
  122. }
  123.  
  124. int
  125. findext(s)
  126.     char       *s;
  127. {
  128.     int         i;
  129.     static char *exts[] = {
  130.     "pic", "pcx", "pal", "clp", "gif", "set", "fnt", "txt"
  131.     };
  132.     static int  extcodes[] = {
  133.     EXT_PIC, EXT_PCX, EXT_PAL, EXT_CLP, EXT_GIF, EXT_SET, EXT_FNT, EXT_TXT
  134.     };
  135.  
  136.     ++s;   /* get past the dot */
  137.     for (i = 0; i < (sizeof exts / sizeof exts[0]); i++)
  138.     if (!strcmp(s, exts[i]))
  139.         return extcodes[i];
  140.     return -1;
  141. }
  142.  
  143. void
  144. stringtofont(ex, i)
  145.     ExecStruct *ex;
  146. {
  147.     int         k;
  148.     char       *s = strtok(ex->Code[i].val.s, ".");
  149.     lowerstr(s);
  150.     for (k = 0; k < numfonts; k++) {
  151.     if (!strcmp(font[k]->name, s)) {
  152.         free(ex->Code[i].val.s);
  153.         ex->Code[i].token = FONTTYPE;
  154.         ex->Code[i].val.font = font[k];
  155.         break;
  156.     }
  157.     }
  158.     if (k == numfonts) {
  159.     fprintf(stderr,"font \"%s\" referenced but not in directory.\n", s);
  160.     ex->Code[i].token = FONTTYPE;
  161.     ex->Code[i].val.font = 0;
  162.     }
  163. }
  164.  
  165. void
  166. stringtoimage(ex, i, deftype)
  167.     ExecStruct *ex;
  168.     int         i;
  169.     int         deftype;
  170. {
  171.     int         k;
  172.     char       *s = strtok(ex->Code[i].val.s, ".");
  173.     char       *ext = strrchr(ex->Code[i].val.s, '.');
  174.     if (ext) {
  175.     int         extcode = findext(ext);
  176.     for (k = 0; k < numimages; k++) {
  177.         if (!strcmp(image[k]->name, s) && image[k]->type == extcode) {
  178.         free(ex->Code[i].val.s);
  179.         ex->Code[i].token = IMAGE;
  180.         ex->Code[i].val.image = image[k];
  181.         break;
  182.         }
  183.     }
  184.     } else {
  185.     for (k = 0; k < numimages; k++) {
  186.         if (!strcmp(image[k]->name, s)) {
  187.         /*
  188.          * this might be the second time through here, so don't free
  189.          * the string more than once...
  190.          */
  191.         if (ex->Code[i].token == STRING) {
  192.             free(ex->Code[i].val.s);
  193.             ex->Code[i].token = IMAGE;
  194.         }
  195.         ex->Code[i].val.image = image[k];
  196.         if (image[k]->type == deftype)
  197.             break;
  198.         }
  199.     }
  200.     }
  201.     if (ex->Code[i].token != IMAGE)
  202.     error("%s: image \"%s\" referenced but not in directory.\n", s);
  203. }
  204.  
  205. void
  206. stringtolabel(ex, i)
  207.     ExecStruct *ex;
  208.     int         i;
  209. {
  210.     int         k;
  211.     char       *s = strtok(ex->Code[i].val.s, ".");
  212.     lowerstr(s);
  213.     for (k = 0; k < ex->numlabels; k++) {
  214.     if (!strcmp(s, ex->label[k].string)) {
  215.         free(ex->Code[i].val.s);
  216.         ex->Code[i].token = INTEGER;
  217.         ex->Code[i].val.i = ex->label[k].ipaddr;
  218.         break;
  219.     }
  220.     if (k == ex->numlabels)
  221.         error("%s: label \"%s\" referenced but not found.\n", s);
  222.     }
  223. }
  224.  
  225. void
  226. stringtoexec(ex, i)
  227.     ExecStruct *ex;
  228.     int         i;
  229. {
  230.     int         k;
  231.     char       *s = strtok(ex->Code[i].val.s, ".");
  232.     lowerstr(s);
  233.     for (k = 0; k < numexecs; k++) {
  234.     if (!strcmp(execRec[k]->name, s)) {
  235.         free(ex->Code[i].val.s);
  236.         ex->Code[i].token = EXECTYPE;
  237.         ex->Code[i].val.exec = execRec[k];
  238.         break;
  239.     }
  240.     }
  241.     if (k == numexecs)
  242.     error("%s: exec \"%s\" referenced but not in directory.\n", s);
  243. }
  244.  
  245.  
  246. int
  247. calcwidth(data, width, height, left)
  248.     u_char     *data;
  249.     int         width;
  250.     int         height;
  251.     int        *left;
  252. {
  253.     int         bpsl = (width + 7) >> 3;
  254.     int         right;
  255.     int         mask;
  256.     int         i;
  257.     int         j;
  258.  
  259. /*find left */
  260.     *left = 0;
  261.     for (i = 0; i < bpsl; i++) {
  262.     for (mask = 0x80; mask > 0; mask >>= 1) {
  263.         for (j = 0; j < height; j++) {
  264.         if (data[j * bpsl + i] & mask)
  265.             goto calcright;
  266.         }
  267.         (*left)++;
  268.     }
  269.     }
  270.     *left = 0;
  271.     return width / 2;    /* must be the space char... */
  272.  
  273. calcright:/* find right */
  274.  
  275.     right = bpsl * 8;
  276.     for (i = bpsl - 1; i >= 0; i--) {
  277.     for (mask = 0x01; mask < 0x100; mask <<= 1) {
  278.         for (j = 0; j < height; j++) {
  279.         if (data[j * bpsl + i] & mask)
  280.             return right - *left;
  281.         }
  282.         right--;
  283.     }
  284.     }
  285.     error("%s: bad width calc.", NULL);
  286. }
  287.  
  288.  
  289. FontStruct *
  290. readfont(fp, dirent)
  291.     FILE       *fp;
  292.     FilenameStruct *dirent;
  293. {
  294.     FontStruct *font;
  295.     XImage      xim;
  296.     int         first;
  297.     int         num;
  298.     u_long      datasize;
  299.     int         i;
  300.     char       *data;
  301.  
  302.     fseek(fp, dirent->offset, 0);
  303.     font = (FontStruct *) malloc((size_t) sizeof(FontStruct));
  304.     assert (font);
  305.     font->name = strtok(strdup(dirent->fname), ".");
  306.     (void) GetLong(fp);    /* skip file length */
  307.     (void) GetWord(fp);    /* skip length */
  308.     if (imverbose)
  309.     hexdump(fp, 4);
  310.     num = GetByte(fp);
  311. /* hack for trashed fonts... */
  312.     if (num == -1) {
  313.     free(font->name);
  314.     free((char *) font);
  315.     return (FontStruct *) 0;
  316.     }
  317.     first = GetByte(fp);
  318.     font->width = GetByte(fp);
  319.     font->height = GetByte(fp);
  320.     datasize = GetByte(fp);
  321.     data = (char *) malloc(datasize);
  322.     if (!data)
  323.     error("%s: couldn't malloc glyph memory\n", NULL);
  324.     if (verbose)
  325.     fprintf(stderr, "%s: (FNT) %d %dx%d,%d(%d) glyphs, from %d to %d\n",
  326.         font->name, num, font->width, font->height,
  327.         datasize, font->height * ((font->width + 7) >> 3),
  328.         first, first + num - 1);
  329.  
  330.  
  331.     xim.height = font->height;
  332.     xim.width = font->width;
  333.     xim.depth = 1;
  334.     xim.xoffset = 0;
  335.     xim.format = XYBitmap;
  336.     xim.data = data;
  337.     xim.byte_order = MSBFirst;
  338.     xim.bitmap_unit = 8;
  339.     xim.bitmap_bit_order = MSBFirst;
  340.     xim.bitmap_pad = 8;
  341.     xim.bytes_per_line = (font->width + 7) / 8;
  342.  
  343.     for (i = 0; i < 256; i++) {
  344.     if (i >= first && i < first + num) {
  345.         fread(data, datasize, 1, fp);
  346.         font->glyphs[i].width = calcwidth((u_char *) data, font->width, font->height,
  347.                           &font->glyphs[i].lbearing);
  348.         font->glyphs[i].pix = XCreatePixmap(dsp, win,
  349.                         font->width, font->height, 1);
  350.         XPutImage(dsp, font->glyphs[i].pix, gc1, &xim, 0, 0, 0, 0,
  351.               font->width, font->height);
  352.     } else {
  353.         font->glyphs[i].pix = (Pixmap) 0;
  354.         font->glyphs[i].width = 0;
  355.         font->glyphs[i].lbearing = 0;
  356.     }
  357.     }
  358.  
  359.  
  360.     free(data);
  361.  
  362.     return font;
  363. }
  364.  
  365.  
  366. FontStruct *
  367. readset(fp, dirent)
  368.     FILE       *fp;
  369.     FilenameStruct *dirent;
  370. {
  371.     FontStruct *font;
  372.     XImage      xim;
  373.     int         first;
  374.     int         num;
  375.     u_long      datasize;
  376.     int         i;
  377.     char       *data;
  378.     char        fontname[14];
  379.     int         type;
  380.     int         checktype;
  381.     int         fontascent;
  382.     int         proportional;
  383.     int         bpsl;
  384.     int         lfgap;
  385.     int         italics;
  386.     int         fntinvert;
  387.     int         fnthbold;
  388.     int         fntvbold;
  389.     int         fnthmag;
  390.     int         fntvmag;
  391.     int         fnthfract;
  392.     int         fntvfract;
  393.     int         fntdirection;
  394.     int         fntrot90;
  395.     int         fnthflip;
  396.     int         fntvflip;
  397.     int         fntcolor;
  398.     int         fntsubtype;
  399.     char        unused[18];
  400.     int         dataofs;
  401.  
  402.     int         celloffs[256];
  403.     int         cellwidth[256];
  404.  
  405.     fseek(fp, dirent->offset, 0);
  406.  
  407.     (void) GetLong(fp);    /* skip file length */
  408.  
  409.     if (imverbose)
  410.     hexdump(fp, 4);
  411.  
  412.     /* non-compressed type = 0x10 or compressed type = 0x14 */
  413.     type = GetByte(fp);
  414.     if (type != 0x10 && type != 0x14)
  415.     return readfont(fp, dirent);
  416.  
  417.     fread(fontname, 13, 1, fp);
  418.     fontname[13] = 0;
  419.     /* non-compressed font = 0xba, compressed font = 0xdc */
  420.     checktype = GetByte(fp);
  421.  
  422.     font = (FontStruct *) malloc((size_t) sizeof(FontStruct));
  423.     assert (font);
  424.     font->name = strtok(strdup(dirent->fname), ".");
  425.  
  426.     fontascent = GetByte(fp);
  427.     num = GetByte(fp);
  428.     /* limited to the lower 94 ASCII characters: 0x21 - 0x7E */
  429.     first = GetByte(fp) + 0x20;
  430.     proportional = GetByte(fp);    /* 0 = non-proportional */
  431.     font->width = GetByte(fp);
  432.     font->height = GetByte(fp);
  433.     bpsl = GetByte(fp);
  434.     datasize = font->height * bpsl;
  435.     spacegap = GetByte(fp);
  436.     chargap = GetByte(fp);
  437.     lfgap = GetByte(fp);
  438.     (void) GetWord(fp);    /* skip file length */
  439.     italics = GetByte(fp);
  440.  
  441.     fntinvert = GetByte(fp);    /* 0 = dont invert, 1 = invert */
  442.     fnthbold = GetByte(fp);    /* number of overlapping bits horizontal */
  443.     fntvbold = GetByte(fp);    /* number of overlapping bits vertical */
  444.     fnthmag = GetByte(fp);    /* integral horizontal bit magnification */
  445.     fntvmag = GetByte(fp);    /* integral vertical bit magnification */
  446.     fnthfract = GetByte(fp);    /* fractional horizontal bit magnification */
  447.     fntvfract = GetByte(fp);    /* fractional vertical bit magnification */
  448.     fntdirection = GetByte(fp);    /* Print direction 0 = left to right, 1...3 =
  449.                  * counterclock 1...3 */
  450.     fntrot90 = GetByte(fp);    /* rotation 0 = up, 1...3 = counterclock 1...3 */
  451.     fnthflip = GetByte(fp);    /* horizontal flip 0 = no, 1 = yes */
  452.     fntvflip = GetByte(fp);    /* vertical flip 0 = no, 1 = yes */
  453.     fntcolor = GetByte(fp);    /* color of font */
  454.     fntsubtype = GetByte(fp);    /* subcategory type of this font */
  455.     fread(unused, 18, 1, fp);
  456.  
  457.     if (verbose)
  458.     fprintf(stderr, "%s[%s]: (SET) %d %dx%d,%d %sglyphs, from %d to %d\n",
  459.         font->name, fontname, num, font->width, font->height, datasize,
  460.         proportional ? "var-" : "fixed-", first, first + num - 1);
  461.  
  462.     if (type == 0x10) {
  463.     for (i = 0; i <= num; i++)
  464.         celloffs[i] = GetWord(fp);
  465.     if (proportional) {
  466.         for (i = 0; i <= num; i++)
  467.         cellwidth[i] = GetByte(fp);
  468.     }
  469.     dataofs = ftell(fp) - dirent->offset + 4;
  470.     data = (char *) malloc(datasize * num);
  471.     if (!data)
  472.         error("%s: couldn't malloc glyph memory\n", NULL);
  473.     fread(data, num, datasize, fp);
  474.  
  475.     xim.width = font->width;
  476.     xim.height = font->height;
  477.     xim.depth = 1;
  478.     xim.xoffset = 0;
  479.     xim.format = XYBitmap;
  480.     xim.data = 0;
  481.     xim.byte_order = MSBFirst;
  482.     xim.bitmap_unit = 8;
  483.     xim.bitmap_bit_order = MSBFirst;
  484.     xim.bitmap_pad = 8;
  485.     xim.bytes_per_line = bpsl;
  486.  
  487.     for (i = 0; i < 256; i++) {
  488.         font->glyphs[i].pix = (Pixmap) 0;
  489.         font->glyphs[i].width = 0;
  490.         font->glyphs[i].lbearing = 0;
  491.     }
  492.  
  493.     for (i = 0; i <= num; i++) {
  494.         int         j = first + i - 1;
  495.  
  496.         font->glyphs[j].lbearing = 0;
  497.         font->glyphs[j].width = proportional ? cellwidth[i] : font->width;
  498.         font->glyphs[j].pix = XCreatePixmap(dsp, win,
  499.                       font->glyphs[j].width, font->height, 1);
  500.         xim.data = &data[celloffs[i] - dataofs];
  501.         XPutImage(dsp, font->glyphs[j].pix, gc1, &xim, 0, 0, 0, 0,
  502.               font->glyphs[j].width, font->height);
  503.     }
  504.  
  505.     free(data);
  506.  
  507.     } else {
  508.     fprintf(stderr,"don't do compressed SET's yet.\n");
  509.     }
  510.     return font;
  511. }
  512.  
  513.  
  514. #define fixcolr(c)   ((c * 255 / maxcolorval) << 8)
  515.  
  516.  
  517.     static void
  518. CheckColorMap (ImageStruct *pIm, short maxcolorval)
  519.  
  520. {
  521.     if (pIm /* != (ImageStruct *) NULL */ && pIm->cmaplen /* > 0 */)
  522.     {
  523.         register short    i;
  524.         char        fIsNonZero = 0;
  525.  
  526.  
  527.     for (i = 0; i < pIm->cmaplen; i++)
  528.     {
  529.         short   r = pIm->colors[i].red   >> 8;
  530.         short   g = pIm->colors[i].green >> 8;
  531.         short   b = pIm->colors[i].blue  >> 8;
  532.  
  533.  
  534.         fIsNonZero |= r | g | b;
  535.     }
  536.  
  537.     if (!fIsNonZero)
  538.     {
  539.         for (i = 0; i < pIm->cmaplen; i++)
  540.         {
  541.             u_short    theColor = fixcolr (i);
  542.  
  543.  
  544.         pIm->colors[i].red   = theColor;
  545.         pIm->colors[i].green = theColor;
  546.         pIm->colors[i].blue  = theColor;
  547.         }
  548.     }
  549.     }
  550. }
  551.  
  552.  
  553. ImageStruct *
  554. readimage(fp, dirent, filetype)
  555.     FILE       *fp;
  556.     FilenameStruct *dirent;
  557.     int         filetype;
  558. {
  559.     ImageStruct *im;
  560.     XImage     *xim;
  561.     int         i;
  562.     int         j;
  563.     int         format;
  564.     long        bpsl;
  565.     int         blocks;
  566.     u_long      datasize;
  567.     long        blockoffset;
  568.     u_char     *ptr;
  569.     int         bpp;
  570.     int         planes;
  571.     u_long      idx;
  572.     int         magic;
  573.     int         unknown;
  574.     int         type;
  575.     int         edesc;
  576.     int         exsize;
  577.     short       maxcolorval;
  578.     u_long      pixels[256];
  579.     u_long      pmasks;
  580.     u_long      filelen;
  581.     char       *pDupName;
  582.     char    fIsScrnText = 0;
  583.  
  584.  
  585.     im = (ImageStruct *) malloc((size_t) sizeof(ImageStruct));
  586.     assert (im);
  587.  
  588.     fseek(fp, dirent->offset, 0);
  589.  
  590.     filelen = GetLong(fp);    /* length of whole image file... */
  591.  
  592.     if (imverbose)
  593.     hexdump(fp, 4);
  594.  
  595.     pDupName = strdup(dirent->fname);
  596.     im->name = strtok(pDupName, ".");
  597.     im->type = filetype;
  598.  
  599.     magic = GetWord(fp);
  600.     if (magic != 0x1234) {    /* I'm guessing here */
  601.     im->w = GetWord(fp);
  602.     im->h = GetWord(fp);
  603.     fprintf(stderr,"\nstrange magic, maybe bad data\n");
  604.     fprintf(stderr,"%dx%d %d, %d, %d, %ld\n", im->w, im->h, im->w * im->h / 4,
  605.            magic - 6, ((im->w + 3) >> 2) * im->h, filelen - 6);
  606.  
  607. #if 0
  608.     return NULL;
  609. #endif
  610.  
  611. /* found in magic.gl
  612. "15934x16190 64492865, 15928, 64500960, 1044266552"
  613. im->w  im->h  w*h/4   magic-6  (w+3)>>2)*h  filelen-6
  614.  
  615. magic == im.w
  616.  
  617. */
  618.     im->xoff = 0;
  619.     im->yoff = 0;
  620.     bpp = 1;
  621.     planes = 1;
  622.     type = 'a';
  623.     edesc = 1;
  624.     exsize = 0;
  625.     } else {
  626.     im->w = GetWord(fp);
  627.     im->h = GetWord(fp);
  628.     im->xoff = GetWord(fp);
  629.     im->yoff = GetWord(fp);
  630.     bpp = GetByte(fp);
  631.     planes = ((bpp & 0xf0) >> 4) + 1;
  632.     bpp &= 0x0f;
  633.     if (GetByte(fp) != 0xff)
  634.         error("%s: %s is corrupt\n", im->name);
  635.     type = GetByte(fp);
  636.     edesc = GetWord(fp);
  637.     exsize = GetWord(fp);
  638.  
  639.     fIsScrnText = ('0' <= type && type <= '3');
  640.     }
  641.  
  642.     if (bpp == 1 && planes == 1) {
  643.     im->d = 1;
  644.     format = XYBitmap;
  645.     bpsl = (im->w + 7) >> 3;
  646. #if 0
  647.     XSetForeground(dsp, gc, whiteC);
  648.     XSetBackground(dsp, gc, blackC);
  649. #else
  650.     XSetBlackAndWhite (dsp, win);
  651. #endif
  652.     } else {
  653.     im->d = 8;
  654.     format = fIsScrnText ? TextImage : ZPixmap;
  655.     bpsl = im->w;
  656.     }
  657.     datasize = bpsl * im->h;
  658.     ptr = (u_char *) malloc(datasize);
  659.     if (!ptr)
  660.     error("%s: readimage: malloc failed on image data.\n", NULL);
  661.  
  662.     if (verbose)
  663.     fprintf(stderr,
  664.      "%s: (PIC) %dx%dx%d(%1x:%1x) [%d,%d] sz=%ld t=%c edesc=%02x ext=%d\n",
  665.            im->name,
  666.            im->w,
  667.            im->h,
  668.            im->d,
  669.            bpp, planes,
  670.            im->xoff,
  671.            im->yoff,
  672.            datasize,
  673.            type,
  674.            edesc,
  675.            exsize);
  676.  
  677.     if (edesc != 0)
  678.       im->cmap = XCreateColormap(dsp, win, vis, AllocNone);
  679.  
  680.     switch (edesc) {
  681.     case 0:
  682.     im->cmaplen = 0;
  683.     im->cmap = (Colormap) 0;
  684.     break;
  685.     case 1:
  686.     im->cmaplen = 4;
  687.     break;
  688.     case 2:
  689.     im->cmaplen = 16;
  690.     maxcolorval = 15;
  691.     break;
  692.     case 3:
  693.     im->cmaplen = 16;
  694.     maxcolorval = 63;
  695.     break;
  696.     case 4:
  697.     im->cmaplen = 256;
  698.     maxcolorval = 63;
  699.     break;
  700.     case 5:
  701.     im->cmaplen = 16;
  702.     maxcolorval = 63;
  703.     break;
  704.     default:
  705.     error("%s: bad edesc: %d\n", (char *) edesc);
  706.     }
  707.  
  708.    if (im->cmaplen > 0)
  709.      XAllocColorCells(dsp, im->cmap, True, (unsigned long *) &pmasks,
  710.                       0, (unsigned long *) pixels, im->cmaplen);
  711.  
  712.     switch (edesc) {
  713.     case 0:
  714.     break;
  715.     case 1:
  716.     {
  717.         char        pal;
  718.  
  719.         if (exsize != 2)
  720.         error("%s: unexpected esize: %d\n", (char *) exsize);
  721.         pal = GetByte(fp);
  722.         j = GetByte(fp);
  723.         i = 0;
  724.  
  725.         im->colors[i].pixel = pixels[i];
  726.         im->colors[i].red = egapal[j][0];
  727.         im->colors[i].green = egapal[j][1];
  728.         im->colors[i].blue = egapal[j][2];
  729.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  730.         for (i = 1; i < im->cmaplen; i++) {
  731.         j = cgapal[i - 1][pal];
  732.         im->colors[i].pixel = pixels[i];
  733.         im->colors[i].red = egapal[j][0];
  734.         im->colors[i].green = egapal[j][1];
  735.         im->colors[i].blue = egapal[j][2];
  736.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  737.         }
  738.     }
  739.     break;
  740.     case 2:
  741.     case 3:
  742.     if (exsize != im->cmaplen)
  743.         error("%s: bad exsize: %d\n", (char *) exsize);
  744.     for (i = 0; i < im->cmaplen; i++) {
  745.         int         pal = GetByte(fp);
  746.         im->colors[i].pixel = pixels[i];
  747.         im->colors[i].red = decodepal(pal, 0x20, 0x04) << 8;
  748.         im->colors[i].green = decodepal(pal, 0x10, 0x02) << 8;
  749.         im->colors[i].blue = decodepal(pal, 0x08, 0x01) << 8;
  750.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  751.     }
  752.     break;
  753.     case 4:
  754.     case 5:
  755.     {
  756.     if (exsize != 0 && exsize != im->cmaplen * 3)
  757.         fprintf(stderr,"bad exsize: %d\n", exsize);
  758.  
  759.     for (i = 0; i < im->cmaplen; i++) {
  760.         unsigned short r,g,b;
  761.         im->colors[i].pixel = pixels[i];
  762.         im->colors[i].red = fixcolr(r=GetByte(fp));
  763.         im->colors[i].green = fixcolr(g=GetByte(fp));
  764.         im->colors[i].blue = fixcolr(b=GetByte(fp));
  765.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  766.     }
  767.     break;
  768.     }
  769.     }
  770.  
  771.     if (edesc > 0)
  772.     {
  773.     CheckColorMap (im, maxcolorval);
  774.  
  775.     if (verbose) {
  776.         fprintf(stderr,"%d colors\n", im->cmaplen);
  777.         /*----
  778.         for (i = 0; i < im->cmaplen; i++) {
  779.         fprintf(stderr,"%02x%02x%02x ",
  780.                im->colors[i].red >> 8,
  781.                im->colors[i].green >> 8,
  782.                im->colors[i].blue >> 8);
  783.         if (!((i + 1) % 8))
  784.             fprintf(stderr,"\n");
  785.         }
  786.         -----*/
  787.     }
  788.     XStoreColors(dsp, im->cmap, im->colors, im->cmaplen);
  789.     }
  790.     if (magic != 0x1234) {    /* BSAVE */
  791.     fread(ptr, filelen - 6, 1, fp);
  792.     } else {
  793.     blocks = GetWord(fp);
  794.     if (blocks == 0) {
  795.         if (imverbose)
  796.         fprintf(stderr,"unpacked data\n");
  797.         fread(ptr, datasize, 1, fp);
  798.     } else {
  799.  
  800.         if (imverbose) {
  801.         fprintf(stderr,"%d image blocks\n", blocks);
  802.         hexdump(fp, 4);
  803.         }
  804.         blockoffset = ftell(fp);
  805.         idx = 0;
  806.         for (i = 0; i < blocks; i++) {
  807.         u_char      esc;
  808.         int         rlebytes;
  809.         int         bufsize;
  810.  
  811.         fseek(fp, blockoffset, 0);
  812.  
  813.         rlebytes = GetWord(fp);
  814.         bufsize = GetWord(fp);
  815.         esc = GetByte(fp);
  816.  
  817.         blockoffset += rlebytes;
  818.  
  819.         if (imverbose) {
  820.             fprintf(stderr,"block: %d (len = %d) (bufsize = %d) (esc = %d)\n",
  821.                i, rlebytes, bufsize, esc);
  822.             hexdump(fp, 4);
  823.         }
  824.         rlebytes -= 5;
  825.         while (rlebytes) {
  826.             u_char      c = GetByte(fp);
  827.             rlebytes--;
  828.             if (c == esc) {
  829.             u_int       count = GetByte(fp);
  830.             rlebytes--;
  831.             if (count == 0) {
  832.                 count = GetWord(fp);
  833.                 rlebytes -= 2;
  834.             }
  835.             c = GetByte(fp);
  836.             rlebytes--;
  837. #if 1
  838.             if (idx + count > datasize) {
  839.                 fprintf(stderr, "*");
  840.                 goto bailimage;
  841.             }
  842. #endif
  843.             memset(&ptr[idx], c, count);
  844.             idx += count;
  845.             } else {
  846. #if 1
  847.             if (idx + 1 > datasize) {
  848.                 fprintf(stderr, "*");
  849.                 goto bailimage;
  850.             }
  851. #endif
  852.             ptr[idx] = c;
  853.             idx++;
  854.             }
  855.         }
  856.         }
  857.     }
  858.     }
  859. bailimage:
  860.  
  861.     switch (bpp) {
  862.     case 1:
  863.     switch (planes) {
  864.     case 1:
  865.     {
  866.         ptr = processVideoC (ptr, &datasize, &bpsl, im);
  867.         if (FDoSmallVideoC ())
  868.         ptr = shrinkVideoC  (ptr, &datasize, &bpsl, im);
  869.  
  870.         break;
  871.     }
  872.     case 2:
  873.     case 3:
  874.         error("%s: %d plane decoding not implemented\n", (char *) planes);
  875.         break;
  876.     case 4:
  877.         {
  878.         u_char     *dst;
  879.         u_char     *src;
  880.         u_char     *old;
  881.         u_long      srcbpsl = (im->w + 7) >> 3;
  882.         u_long      plane0 = srcbpsl * 0 * im->h;
  883.         u_long      plane1 = srcbpsl * 1 * im->h;
  884.         u_long      plane2 = srcbpsl * 2 * im->h;
  885.         u_long      plane3 = srcbpsl * 3 * im->h;
  886.  
  887.         src = old = ptr;
  888.         dst = ptr = (u_char *) malloc(datasize);
  889.  
  890.         if (!dst)
  891.             error("%s: readimage:4: malloc failed on image data.\n", NULL);
  892.  
  893.         for (j = 0; j < im->h; j++) {
  894.             int         mask = 0x80;
  895.             u_long      addr = (u_long) j * srcbpsl;
  896.  
  897.  
  898.             for (i = 0; i < im->w; i++, mask >>= 1) {
  899.             if (mask == 0) {
  900.                 mask = 0x80;
  901.                 addr++;
  902.             }
  903.             *dst++ = ((src[plane0 + addr] & mask) != 0) +
  904.                 2 * ((src[plane1 + addr] & mask) != 0) +
  905.                 4 * ((src[plane2 + addr] & mask) != 0) +
  906.                 8 * ((src[plane3 + addr] & mask) != 0);
  907.             }
  908.         }
  909.         free((char *) old);
  910.         }
  911.         break;
  912.     }
  913.     break;
  914.     case 2:
  915.     switch (planes) {
  916.     case 1:
  917.         {
  918.         u_char     *dst;
  919.         u_char     *src;
  920.         u_char     *old;
  921.         int         rem;
  922.  
  923.         src = old = ptr;
  924.         dst = ptr = (u_char *) malloc(datasize);
  925.  
  926.         if (!dst)
  927.             error("%s: readimage:2: malloc failed on image data.\n", NULL);
  928.  
  929.         rem = im->w & 3;
  930.         for (i = 0; i < im->h; i++) {
  931.             for (j = 0; j < im->w >> 2; j++) {
  932.             *dst++ = *src >> 6 & 3;
  933.             *dst++ = *src >> 4 & 3;
  934.             *dst++ = *src >> 2 & 3;
  935.             *dst++ = *src >> 0 & 3;
  936.             src++;
  937.             }
  938.             switch (rem) {
  939.             case 3:
  940.             dst[2] = *src >> 2 & 3;
  941.             case 2:
  942.             dst[1] = *src >> 4 & 3;
  943.             case 1:
  944.             dst[0] = *src >> 6 & 3;
  945.             src++;
  946.             dst += rem;
  947.             case 0:
  948.             break;
  949.             }
  950.         }
  951.         free((char *) old);
  952.         }
  953.         break;
  954.     default:
  955.         error("%s: %d plane decoding not implemented\n", (char *) planes);
  956.         break;
  957.     }
  958.     break;
  959.     case 4:
  960.     {
  961.         u_char     *dst;
  962.         u_char     *src;
  963.         u_char     *old;
  964.  
  965.         src = old = ptr;
  966.         dst = ptr = (u_char *) malloc(datasize);
  967.  
  968.         if (!dst)
  969.         error("%s: readimage:4b: malloc failed on image data.\n", NULL);
  970.  
  971.         for (i = 0; i < im->h; i++) {
  972.         for (j = 0; j < im->w / 2; j++) {
  973.             *dst++ = *src >> 4 & 0xf;
  974.             *dst++ = *src >> 0 & 0xf;
  975.             src++;
  976.         }
  977.         }
  978.         free((char *) old);
  979.     }
  980.     break;
  981.     case 8:
  982.     break;
  983.     }
  984.  
  985. /* invert the image top to bottom */
  986. // is this where we mess up left edge -> right edge ??
  987.    {
  988.     u_char     *buffer;
  989.  
  990.     buffer = (u_char *) malloc(bpsl);
  991.     assert (buffer);
  992.  
  993.     for (i = 0; i < im->h / 2; i++) {
  994.         memcpy(buffer, ptr + (im->h - i - 1) * bpsl, bpsl);
  995.         memcpy(ptr + (im->h - i - 1) * bpsl, ptr + i * bpsl, bpsl);
  996.         memcpy(ptr + i * bpsl, buffer, bpsl);
  997.     }
  998.     free((char *) buffer);
  999.     }
  1000.  
  1001.     xim = XCreateImage(dsp, vis, im->d, format, 0, (char *) ptr, im->w, im->h, 8, bpsl);
  1002.     //im->pix = XCreatePixmap(dsp, win, im->w, im->h, 8);
  1003.     //XPutImage(dsp, im->pix, gc, xim, 0, 0, 0, 0, im->w, im->h);
  1004.     //XSync(dsp, False);
  1005.     // mac, non-X fix
  1006.     im->w= xim->width; // patch in case CreateImage needed to change size
  1007.     im->h= xim->height;
  1008.     im->pix = (Pixmap) xim;
  1009.  
  1010.     return im;
  1011. }
  1012.  
  1013.  
  1014. ImageStruct *
  1015. readpcximage(fp, dirent)
  1016.     FILE       *fp;
  1017.     FilenameStruct *dirent;
  1018. {
  1019.     ImageStruct *im;
  1020.     XImage     *xim;
  1021.     u_long      i;
  1022.     u_char      pcxhd[128];
  1023.     int         magic;
  1024.     int         version;
  1025.     int         encoded;
  1026.     int         bpp;
  1027.     int         xmin, ymin, xmax, ymax;
  1028.     int         planes;
  1029.     u_long      bpsl;
  1030.  
  1031.     u_long      datasize;
  1032.     u_char     *ptr;
  1033.     int         maxcolorval;
  1034.     u_long      pixels[256];
  1035.     u_long      pmasks;
  1036.     u_long      filelen;
  1037.     int         format;
  1038.     char    *pDupName;
  1039.  
  1040.  
  1041.     im = (ImageStruct *) malloc((size_t) sizeof(ImageStruct));
  1042.     assert (im);
  1043.  
  1044.     fseek(fp, dirent->offset, 0);
  1045.  
  1046.     filelen = GetLong(fp);    /* length of whole image file... */
  1047.  
  1048.     if (imverbose)
  1049.     hexdump(fp, 4);
  1050.  
  1051.     pDupName = strdup(dirent->fname);
  1052.     im->name = strtok(pDupName, ".");
  1053.     im->type = EXT_PCX;
  1054.  
  1055.     fread(pcxhd, 128, 1, fp);
  1056.     magic = pcxhd[0];
  1057.     if (magic != 0x0a)
  1058.     fprintf(stderr,"I don't think this is really a .pcx file!\n");
  1059.     version = pcxhd[1];
  1060.     encoded = pcxhd[2];
  1061.     xmin = pcxhd[4] + (256 * pcxhd[5]);
  1062.     ymin = pcxhd[6] + (256 * pcxhd[7]);
  1063.     xmax = pcxhd[8] + (256 * pcxhd[9]);
  1064.     ymax = pcxhd[10] + (256 * pcxhd[11]);
  1065.     im->w = xmax - xmin + 1;
  1066.     im->h = ymax - ymin + 1;
  1067.     im->xoff = im->yoff = 0;
  1068.     bpsl = pcxhd[66] + (256 * pcxhd[67]);
  1069.     bpp = pcxhd[3];
  1070.     planes = pcxhd[65];
  1071.  
  1072.     if (bpp == 1 && planes == 1) {
  1073.     im->d = 1;
  1074.     format = XYBitmap;
  1075. #if 0
  1076.     XSetForeground(dsp, gc, whiteC);
  1077.     XSetBackground(dsp, gc, blackC);
  1078. #else
  1079.     XSetBlackAndWhite (dsp, win);
  1080. #endif
  1081.     } else {
  1082.     im->d = 8;
  1083.     format = ZPixmap;
  1084.     bpsl = im->w;
  1085.     }
  1086.     datasize = bpsl * im->h;
  1087.     ptr = (u_char *) malloc(datasize);
  1088.     if (!ptr)
  1089.     error("%s: readpcximage: malloc failed on image data.\n", NULL);
  1090.  
  1091.     if (verbose)
  1092.     fprintf(stderr,"%s: (PCX) %dx%dx%d(%1x:%1x) [%d,%d] sz=%ld ver=%d enc=%d\n",
  1093.            im->name,
  1094.            im->w,
  1095.            im->h,
  1096.            im->d,
  1097.            bpp, planes,
  1098.            im->xoff,
  1099.            im->yoff,
  1100.            datasize,
  1101.            version,
  1102.            encoded);
  1103.  
  1104.     if (version != 0)
  1105.     im->cmap = XCreateColormap(dsp, win, vis, AllocNone);
  1106.  
  1107.     switch (version) {
  1108.     case 0:
  1109.     case 3:
  1110.     im->cmaplen = 0;
  1111.     im->cmap = (Colormap) 0;
  1112.     break;
  1113.     case 2:
  1114.     im->cmaplen = 16;
  1115.     maxcolorval = 255;
  1116.     break;
  1117.     case 5:
  1118.     im->cmaplen = 256;
  1119.     maxcolorval = 255;
  1120.     break;
  1121.     case 1:
  1122.     case 4:
  1123.     default:
  1124.     error("%s: bad pcx version: %d\n", (char *) version);
  1125.     }
  1126.  
  1127.     if (im->cmaplen > 0)
  1128.     XAllocColorCells(dsp, im->cmap, True, (unsigned long *) &pmasks,
  1129.                      0, (unsigned long *) pixels, im->cmaplen);
  1130.  
  1131.     switch (version) {
  1132.     case 0:
  1133.     case 3:
  1134.     break;
  1135.     case 2:    /* I'm guessing here! */
  1136.     for (i = 0; i < im->cmaplen; i++) {
  1137.         im->colors[i].pixel = pixels[i];
  1138.         im->colors[i].red = pcxhd[16 + i + 0] << 8;
  1139.         im->colors[i].green = pcxhd[16 + i + 1] << 8;
  1140.         im->colors[i].blue = pcxhd[16 + i + 2] << 8;
  1141.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  1142.     }
  1143.     break;
  1144.     case 5:
  1145.     fseek(fp, dirent->offset + filelen + 4 - 769, 0);
  1146.     if (GetByte(fp) != 12)
  1147.         fprintf(stderr,"I don't think this is a VGA palette.\n");
  1148.     for (i = 0; i < im->cmaplen; i++) {
  1149.         im->colors[i].pixel = pixels[i];
  1150.         im->colors[i].red = GetByte(fp) << 8;
  1151.         im->colors[i].green = GetByte(fp) << 8;
  1152.         im->colors[i].blue = GetByte(fp) << 8;
  1153.         im->colors[i].flags = DoRed | DoGreen | DoBlue;
  1154.     }
  1155.     fseek(fp, dirent->offset + 4 + 128, 0);
  1156.     break;
  1157.     }
  1158.  
  1159.     if (version > 0)
  1160.     {
  1161.         CheckColorMap (im, maxcolorval);
  1162.  
  1163.     if (imverbose) {
  1164.         fprintf(stderr,"%d colors\n", im->cmaplen);
  1165.         /*---
  1166.         for (i = 0; i < im->cmaplen; i++) {
  1167.         fprintf(stderr,"%02x%02x%02x ",
  1168.                im->colors[i].red >> 8,
  1169.                im->colors[i].green >> 8,
  1170.                im->colors[i].blue >> 8);
  1171.         if (!((i + 1) % 8))
  1172.             fprintf(stderr,"\n");
  1173.         }
  1174.        ---*/
  1175.     }
  1176.         XStoreColors(dsp, im->cmap, im->colors, im->cmaplen);
  1177.     }
  1178.     if (encoded) {
  1179.     /*
  1180.      * Goes like this: Read a byte.  If the two high bits are set, then the
  1181.      * low 6 bits contain a repeat count, and the byte to repeat is the
  1182.      * next byte in the file.  If the two high bits are not set, then this
  1183.      * is the byte to write.
  1184.      */
  1185.  
  1186.     i = 0;
  1187.  
  1188.     while (i < datasize)
  1189.     {
  1190.         int    byte = GetByte(fp);
  1191.  
  1192.  
  1193.         if ((byte & 0xc0) == 0xc0)
  1194.         {
  1195.         int         count = byte & 0x3f;
  1196.         int value = GetByte(fp);
  1197.  
  1198.  
  1199.         if (i + count > datasize)
  1200.             count = datasize - i - 1;    /* catch overflow */
  1201.         memset (ptr + i, value, count);
  1202.         i += count;
  1203.         }
  1204.         else
  1205.         {
  1206.         ptr[i++] = byte;
  1207.         }
  1208.     }
  1209.     }
  1210.     else
  1211.     fread(ptr, datasize, 1, fp);
  1212.  
  1213.     /*
  1214.      * need to do planar -> chunky conversion here if we support > 1 plane pcx
  1215.      * files.
  1216.      */
  1217.  
  1218.     xim = XCreateImage(dsp, vis, im->d, format, 0, (char *) ptr, im->w, im->h, 8, bpsl);
  1219. /*****
  1220.     im->pix = XCreatePixmap(dsp, win, im->w, im->h, 8);
  1221.     XPutImage(dsp, im->pix, gc, xim, 0, 0, 0, 0, im->w, im->h);
  1222.     XSync(dsp, False);
  1223. *****/
  1224.     // mac, non-X fix
  1225.     im->w= xim->width; // patch in case CreateImage needed to change size
  1226.     im->h= xim->height;
  1227.     im->pix = (Pixmap) xim;
  1228.  
  1229.     return im;
  1230. }
  1231.  
  1232.  
  1233. void
  1234. printcodes(ex)
  1235.     ExecStruct *ex;
  1236. {
  1237.     int         i;
  1238.     for (i = 0; i < ex->numcodes; i++) {
  1239.     fprintf(stderr,"%4d: ", i);
  1240.     if (ex->Code[i].token < NTOKENS)
  1241.         fprintf(stderr,"[TOK] %s (%d) (%d args)\n",
  1242.            tokens[ex->Code[i].token], ex->Code[i].token,
  1243.            ex->Code[i].val.i);
  1244.     else {
  1245.         switch (ex->Code[i].token) {
  1246.         case INTEGER:
  1247.         fprintf(stderr,"[INT] %d\n", ex->Code[i].val.i);
  1248.         break;
  1249.         case STRING:
  1250.         fprintf(stderr,"[STR] \"%s\"\n", ex->Code[i].val.s);
  1251.         break;
  1252.         case IMAGE:
  1253.         fprintf(stderr,"[IMG] \"%s\"\n", ex->Code[i].val.image->name);
  1254.         break;
  1255.         case FONTTYPE:
  1256.         fprintf(stderr,"[FNT] \"%s\"\n", ex->Code[i].val.font->name);
  1257.         break;
  1258.         case EXECTYPE:
  1259.         fprintf(stderr,"[EXC] \"%s\"\n", ex->Code[i].val.exec->name);
  1260.         break;
  1261.         case WILDTYPE:
  1262.         fprintf(stderr,"[WLD] \"@\"\n");
  1263.         break;
  1264.         default:
  1265.         error("%s: printcodes bogosity (%d)\n", (char *) ex->Code[i].token);
  1266.         }
  1267.     }
  1268.     }
  1269.     fprintf(stderr,"labels:\n");
  1270.     for (i = 0; i < ex->numlabels; i++)
  1271.     fprintf(stderr,"[LABEL] \"%s\" %d\n", ex->label[i].string, ex->label[i].ipaddr);
  1272. }
  1273.  
  1274.  
  1275. /* turn all cload and pload args into pointers to the
  1276.  * actual image structure instead of the filename
  1277.  * turn all fload args into pointers to the font structure
  1278.  * instead of the filename, and change the '@' string to a WILDTYPE.
  1279.  */
  1280. void
  1281. converttypes(ex)
  1282.     ExecStruct *ex;
  1283. {
  1284.     int         i, j;
  1285.     for (i = 0; i < ex->numcodes; i++) {
  1286.     int         t = ex->Code[i].token;
  1287.     char       *s = ex->Code[i].val.s;
  1288.     char        nargs = ex->Code[i].val.i;
  1289.  
  1290.     switch (t) {
  1291.     case STRING:
  1292.         if (s[0] == '@' && s[1] == 0) {
  1293.         ex->Code[i].token = WILDTYPE;
  1294.         ex->Code[i].val.i = 0;
  1295.         }
  1296.         break;
  1297.     case FLOAD:
  1298.         stringtofont(ex, i + 1);
  1299.         break;
  1300.     case CLOAD:
  1301.         stringtoimage(ex, i + 1, EXT_CLP);
  1302.         break;
  1303.     case PLOAD:
  1304.         stringtoimage(ex, i + 1, EXT_PIC);
  1305.         break;
  1306.     case LINK:
  1307.     case CALL:
  1308.         stringtoexec(ex, i + 1);
  1309.         if (nargs > 1)
  1310.         stringtolabel(ex, i + 2);
  1311.         break;
  1312.     case DATABEGIN:
  1313.     case GOTO:
  1314.     case GOSUB:
  1315.         stringtolabel(ex, i + 1);
  1316.         break;
  1317.     case IFKEY:
  1318.         for (j = 2; j <= nargs; j += 2)
  1319.         stringtolabel(ex, i + j);
  1320.         break;
  1321.     case IFMEM:
  1322.     case IFVIDEO:
  1323.     case WAITKEY:
  1324.         if (nargs > 1)
  1325.         stringtolabel(ex, i + 2);
  1326.         break;
  1327.     }
  1328.     }
  1329. }
  1330.  
  1331. ExecStruct *
  1332. readtxt(fp, dir)
  1333.     FILE       *fp;
  1334.     FilenameStruct *dir;
  1335. {
  1336.     ExecStruct *ex;
  1337.     u_long      len;
  1338.     char       *txt;
  1339.     int         i;
  1340.  
  1341.     ex = (ExecStruct *) calloc ((size_t) 1, (size_t) sizeof (ExecStruct));
  1342.     assert (ex);
  1343.     ex->name = strtok(strdup(dir->fname), ".");
  1344.  
  1345.     fseek(fp, dir->offset, 0);
  1346.     len = GetLong(fp);
  1347.     len &= 0x00ffffff;    /* hack */
  1348.     ex->txt = (char *) malloc(len + 1);
  1349.     assert (ex->txt);
  1350.     fread(ex->txt, len, 1, fp);
  1351.     ex->txt[len] = 26;
  1352.     if (showtext)
  1353.     puts(ex->txt);
  1354.     return ex;
  1355. }
  1356.  
  1357.  
  1358. #define ADDIMAGE(im)                        \
  1359. {                                \
  1360.     if (im == (ImageStruct *) NULL &&                \
  1361.         numimages /* > 0 */)                    \
  1362.     {                                \
  1363.         fprintf (stderr,                    \
  1364.              "readfiles () skipped bad image (%d). :-(\n",    \
  1365.              i);                        \
  1366.         im = image[numimages - 1];        /* kluge */    \
  1367.     }                                \
  1368.                                 \
  1369.     if (im /* != (ImageStruct *) NULL */)            \
  1370.     image[numimages++] = im;                \
  1371. }
  1372.  
  1373.  
  1374. void
  1375. readfiles(fp, dir, count)
  1376.     FILE       *fp;
  1377.     FilenameStruct *dir;
  1378.     int         count;
  1379. {
  1380.     int         i;
  1381.     ImageStruct *im;
  1382.  
  1383.     for (i = 0; i < count; i++)
  1384.     {
  1385.     char       *p = strrchr(dir[i].fname, '.');
  1386.     int         extcode;
  1387.  
  1388.  
  1389.     if (!p)
  1390.         error("%s: %s has no extension.\n", dir[i].fname);
  1391.  
  1392.     exitcheck ();
  1393.  
  1394.     extcode = findext(p);
  1395.     switch (extcode) {
  1396.     case EXT_PCX:
  1397.         im = readpcximage(fp, &dir[i]);
  1398.         ADDIMAGE (im);
  1399.         break;
  1400.     case EXT_PIC:
  1401.     case EXT_CLP:
  1402.     case EXT_PAL:
  1403.         im = readimage(fp, &dir[i], extcode);
  1404.         ADDIMAGE (im);
  1405.         break;
  1406.     case EXT_GIF:
  1407.         im = readgifimage (fp, &dir[i]);
  1408.         ADDIMAGE (im);
  1409.         break;
  1410.     case EXT_SET:
  1411.         font[numfonts++] = readset(fp, &dir[i]);
  1412.         if (font[numfonts - 1] == (FontStruct *) 0)
  1413.         --numfonts;
  1414.         break;
  1415.     case EXT_FNT:
  1416.         font[numfonts++] = readfont(fp, &dir[i]);
  1417.         if (font[numfonts - 1] == (FontStruct *) 0)
  1418.         --numfonts;
  1419.         break;
  1420.     case EXT_TXT:
  1421.         execRec[numexecs++] = readtxt(fp, &dir[i]);
  1422.         break;
  1423.     default:
  1424.         if (!fQuiet)
  1425.             fprintf(stderr,"skipping %s: unknown extension.\n", dir[i].fname);
  1426.     }
  1427.     }
  1428.  
  1429.     for (i = 0; i < numexecs; i++)
  1430.     {
  1431.     ExecStruct *ex = execRec[i];
  1432.  
  1433.  
  1434.     exitcheck ();
  1435.  
  1436.     parsefile(ex, ex->txt);
  1437.     converttypes(ex);
  1438.     if (printthecodes)
  1439.         printcodes(ex);
  1440.     }
  1441.  
  1442.     if (imageloop)
  1443.     {
  1444.     short    ithImage;
  1445.     char    fDidVideo1 = 0;
  1446.     short    wMax;
  1447.     short    hMax;
  1448.  
  1449.  
  1450.     for (ithImage = 0; ithImage < numimages; ithImage++)
  1451.     {
  1452.         ImageStruct *pIm  = image[ithImage];
  1453.         XImage    *pXim = (XImage *) pIm->pix;
  1454.  
  1455.  
  1456.         if (pXim->format == TextImage)
  1457.         {
  1458.             if (!fDidVideo1)
  1459.             {
  1460.                 setvideomode ('1');
  1461.                 fDidVideo1 = 1;
  1462.             }
  1463.  
  1464.             continue;
  1465.         }
  1466.  
  1467.         if (ithImage == 0)
  1468.         {
  1469.         picreg[1] = pIm;
  1470.         picreg[2] = pIm;
  1471.  
  1472.         wMax = pIm->w;
  1473.         hMax = pIm->h;
  1474.         }
  1475.         else
  1476.         {
  1477.             if    (pIm->w > picreg[1]->w)
  1478.             {
  1479.                 picreg[1] = pIm;
  1480.                 wMax      = pIm->w;
  1481.             }
  1482.             else if (pIm->h > picreg[2]->h)
  1483.             {
  1484.                 picreg[2] = pIm;
  1485.                 hMax      = pIm->h;
  1486.             }
  1487.         }
  1488.     }
  1489.  
  1490.     if (!fDidVideo1 || picreg[0]->w != wMax || picreg[0]->h != hMax)
  1491.         setvideomode ('?');
  1492.  
  1493.     InitCursor ();
  1494.  
  1495.     MoveTo (9, 140); DrawString ("\pImage loop...");
  1496.     MoveTo (9, 160); DrawString ("\p([Option] click or command-. to continue.)");
  1497.  
  1498.     for (ithImage = -1; ;)
  1499.     {
  1500.         char fShowImage = 0;
  1501.         int     theChar;
  1502.  
  1503.  
  1504.         SystemTask ();
  1505.  
  1506.         if (StopKey ())
  1507.         break;
  1508.  
  1509.         if (MouseButton ())
  1510.         {
  1511.             if    (optionKeyIsDown ())
  1512.                 ithImage--;
  1513.             else if (cmdKeyIsDown ())
  1514.                 ithImage = 0;
  1515.             else
  1516.                 ithImage++;
  1517.  
  1518.             fShowImage = 1;
  1519.         }
  1520.  
  1521.         if (Keypress (&theChar))
  1522.         {
  1523.             fShowImage = 1;
  1524.  
  1525.  
  1526.             switch (theChar)
  1527.             {
  1528.             case 0x01:        /*  home    */
  1529.             case 0x1E:        /*  up arrow    */
  1530.                 ithImage = 0;
  1531.                 break;
  1532.  
  1533.             case 0x04:        /*  end        */
  1534.             case 0x1F:        /*  down arrow  */
  1535.                 ithImage = numimages - 1;
  1536.                 break;
  1537.  
  1538.             case 0x1C:        /*  left arrow    */
  1539.             case 0x0B:        /*  page up    */
  1540.                 ithImage--;
  1541.                 break;
  1542.  
  1543.             case 0x1D:        /*  right arrow */
  1544.             case 0x0C:        /*  page down    */
  1545.                 ithImage++;
  1546.                 break;
  1547.  
  1548.             default:
  1549.                 fShowImage = 0;
  1550.                 break;
  1551.         }
  1552.         }
  1553.  
  1554.         if (fShowImage)
  1555.         {
  1556.             ImageStruct    *pIm;
  1557.             XImage        *pXim;
  1558.  
  1559.  
  1560.         if (ithImage >= numimages)
  1561.             ithImage = 0;
  1562.         else if (ithImage < 0)
  1563.             ithImage = numimages - 1;
  1564.  
  1565.         pIm = image[ithImage];
  1566.  
  1567.         pXim = (XImage *) pIm->pix;
  1568.  
  1569.         if (pIm->d == 1 || pXim->format == TextImage)
  1570.             XSetBlackAndWhite (dsp, win);
  1571.         else if (pIm->cmap /* != (Colormap) NULL */)
  1572.             XSetWindowColormap (dsp, win, pIm->cmap);
  1573.  
  1574.         if (pXim->format == TextImage)
  1575.             imagefade (0, pIm, 0, 0, 0, 0);
  1576.         else
  1577.             XCopyArea (dsp, pIm->pix, win, gc, 0, 0, pIm->w, pIm->h, 0, 0);
  1578.         }
  1579.     }
  1580.     }
  1581. }
  1582.